package com.geovis.emergency.spd.controller.pc;


import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.geovis.common.auth.util.AuthUtil;
import com.geovis.common.core.api.Result;
import com.geovis.common.core.constant.SwaggerConstants;
import com.geovis.common.core.controller.BaseController;
import com.geovis.emergency.spd.biz.command.service.ITEpDisasterService;
import com.geovis.emergency.spd.biz.pc.mapper.PcDrillMapper;
import com.geovis.emergency.spd.biz.pc.service.IPcDrillDisasterEventService;
import com.geovis.emergency.spd.biz.pc.service.IPcDrillDisasterService;
import com.geovis.emergency.spd.entity.command.entity.TEpDisaster;
import com.geovis.emergency.spd.entity.pc.entity.PcDrill;
import com.geovis.emergency.spd.entity.pc.entity.PcDrillDisaster;
import com.geovis.emergency.spd.entity.pc.entity.PcDrillDisasterEvent;
import com.geovis.emergency.spd.entity.pc.pojo.constant.PcDrillConstant;
import com.geovis.emergency.spd.entity.pc.pojo.constant.PcMessageConstant;
import com.geovis.emergency.spd.entity.pc.pojo.dto.PcDrillDisasterEventDTO;
import com.geovis.emergency.spd.entity.pc.pojo.enums.DisasterEventStatusEnum;
import com.geovis.emergency.spd.entity.pc.pojo.vo.PcDrillDisasterEventListVO;
import com.geovis.emergency.spd.entity.pc.pojo.vo.PresetEventVO;
import com.geovis.emergency.spd.util.MsgUtil;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.google.common.collect.Lists;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 应急预案指挥模块-演练灾害消息事件 前端控制器
 * </p>
 *
 * @author Lonsho
 * @since 2022-06-08
 */
@RestController
@RequestMapping("/pc/drill/disaster/event")
@RequiredArgsConstructor
@Api(value = "应急预案指挥模块-演练灾害事件", tags = "应急预案指挥模块-演练灾害事件接口")
@Slf4j
@Validated
public class PcDrillDisasterEventController extends BaseController<IPcDrillDisasterEventService> {
    private final IPcDrillDisasterService pcDrillDisasterService;

    private final PcDrillMapper pcDrillMapper;

    private final ITEpDisasterService tepDisasterService;

    @ApiOperationSupport(order = 1)
    @ApiOperation(value = SwaggerConstants.LIST_VALUE, notes = SwaggerConstants.LIST_VALUE)
    @PostMapping("/getList/{drillId}")
    public Result<List<PcDrillDisasterEventListVO>> getList(@PathVariable("drillId") String drillId, @RequestParam(required = false) String status) {
        return Result.ok(baseService.getList(drillId,status));
    }
    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "下发事件消息", notes = "下发事件消息")
    @PostMapping("/publishEvent/{pcDisasterEventId}")
    public Result<List<PcDrillDisasterEvent>> issued(@RequestBody PcDrillDisasterEventDTO eventDTO) {
        PcDrillDisasterEvent pcDrillDisasterEvent=baseService.publishEvent(eventDTO);
        MsgUtil.sendDrillMsg(pcDrillDisasterEvent.getPcDrillId(), null, PcMessageConstant.TYPE_PUSH_EVENT,pcDrillDisasterEvent.getTitle(),pcDrillDisasterEvent.getContent(),pcDrillDisasterEvent.getId());
        return Result.ok();
    }
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "事件上报", notes = "事件上报")
    @PostMapping("/reportEvent")
    public Result reportEvent(@Validated @RequestBody PcDrillDisasterEventDTO pcDisasterEvent) {
        TEpDisaster tepDisaster=null;
        if(null!=pcDisasterEvent.getSchedulingEventId())
        {
            tepDisaster=tepDisasterService.getById(pcDisasterEvent.getSchedulingEventId());
        }

        PcDrillDisasterEvent pcDrillDisasterEvent=baseService.reportEvent(pcDisasterEvent,tepDisaster,false);
        if(pcDrillDisasterEvent!=null && pcDrillDisasterEvent.getId()!=null)
        {
            MsgUtil.pushMsgByDrillUser(PcMessageConstant.TYPE_REPORT_EVENT,pcDrillDisasterEvent.getTitle(),pcDrillDisasterEvent.getContent(),pcDrillDisasterEvent.getPcDrillId(),pcDrillDisasterEvent.getId());
        }
        return Result.ok();
    }
    @ApiOperationSupport(order = 4)
    @ApiOperation(value = "获取下个预设事件", notes = "获取下个预设事件")
    @PostMapping("/nextEvent/{drillId}/{disasterId}")
    public Result<PresetEventVO> getNextEvent(@PathVariable("drillId") String drillId, @PathVariable("disasterId") String disasterId){
        return Result.ok(baseService.getNextEvent(drillId,disasterId));
    }

    @ApiOperationSupport(order = 5)
    @ApiOperation(value = "根据灾害事件获取演练所有的事件", notes ="根据灾害事件获取演练所有的事件")
    @PostMapping({"/drillDisasterEventList/{pcDisasterId}"})
    public Result<List<PcDrillDisasterEvent>> getDrillDisasterEventList(@PathVariable("pcDisasterId") String pcDisasterId){
        List<String> disasterList = pcDrillDisasterService.list(
                Wrappers.lambdaQuery(PcDrillDisaster.class)
                        .select(PcDrillDisaster::getId)
                        .eq(PcDrillDisaster::getPcDisasterId, pcDisasterId)
        ).stream().map(PcDrillDisaster::getId).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(disasterList)){
            List<PcDrillDisasterEvent> list = baseService.list(
                    Wrappers.lambdaQuery(PcDrillDisasterEvent.class)
                            .in(PcDrillDisasterEvent::getPcDrillDisasterId, disasterList)
                            .and(s -> s.eq(PcDrillDisasterEvent::getStatus, DisasterEventStatusEnum.COMPLETED.getCode()).or()
                                    .eq(PcDrillDisasterEvent::getStatus, DisasterEventStatusEnum.IN_PROGRESS.getCode())
                            )
                            .orderByDesc(PcDrillDisasterEvent::getSubmitTime)
            );
            List<String> drillList = list.stream().map(PcDrillDisasterEvent::getPcDrillId).distinct().collect(Collectors.toList());
            if (CollUtil.isNotEmpty(drillList)){
                //已经启动的演练
                List<String> pcDrillList = pcDrillMapper.selectList(
                        Wrappers.lambdaQuery(PcDrill.class)
                                .select(PcDrill::getId)
                                .ne(PcDrill::getStatus, PcDrillConstant.STATUS_PREPARE)
                                .in(PcDrill::getId, drillList)
                ).stream().map(PcDrill::getStatus).collect(Collectors.toList());
                //只返回已经启动的演练
               if (CollUtil.isEmpty(pcDrillList)){
                   return Result.ok(
                           list.stream().filter(s -> pcDrillList.contains(s.getPcDrillId())).collect(Collectors.toList())
                   );
               }
            }
            return Result.ok(list);
        }else {
            return Result.ok(Lists.newArrayList());
        }
    }
}
